package com.edu.glutdataconvertserver.util;

import com.google.common.collect.Maps;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
    /*

    获取当前时间之前或之后几小时 hour

   */

    public static String getTimeByHour(int hour) {

        Calendar calendar = Calendar.getInstance();

        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + hour);

        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());

    }


    /*

    获取当前时间之前或之后几分钟 minute

    */

    public static String getTimeByMinute(String pattern, int minute) {

        Calendar calendar = Calendar.getInstance();

        calendar.add(Calendar.MINUTE, minute);

        return new SimpleDateFormat(pattern).format(calendar.getTime());

    }

    public static String getTotalSeconds(String time) {
        Date expire = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
        try {
            expire = sdf.parse(time);

        } catch (ParseException e) {
            e.printStackTrace();
        }
        String timestamp = String.valueOf(expire.getTime() / 1000);

        return timestamp;
    }

    public static String getHexSeconds(String time) {
        Date expire = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
        try {
            expire = sdf.parse(time);

        } catch (ParseException e) {
            e.printStackTrace();
        }
        String timestamp = String.valueOf(expire.getTime() / 1000);

        String hex = Integer.toHexString(Integer.parseInt(timestamp));

        return hex;
    }

    private static String[] parsePatterns = new String[]{"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
    /**
     * 每天的毫秒数 8640000.
     */
    public static final long MILLISECONDS_PER_DAY = 86400000L;

    public DateUtils() {
    }

    public static String getDate() {
        return getDate("yyyy-MM-dd");
    }

    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }

    public static String formatDate(Date date, Object... pattern) {
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }

        return formatDate;
    }

    public static String formatDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getTime() {
        return formatDate(new Date(), "HH:mm:ss");
    }

    public static String getDateTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    public static String getWeek() {
        return formatDate(new Date(), "E");
    }

    public static String getWeek(String date) {
        return formatDate(parseDate(date), "E");
    }

    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        } else {
            try {
                return parseDate(str.toString(), parsePatterns);
            } catch (ParseException var2) {
                return null;
            }
        }
    }

    public static Date parseDateFormat(Object str, String pattern) {
        if (str == null) {
            return null;
        } else {
            try {
                return parseDate(str.toString(), new String[]{pattern});
            } catch (ParseException var3) {
                return null;
            }
        }
    }

    public static long pastDays(Date date) {
        long t = (new Date()).getTime() - date.getTime();
        return t / 86400000L;
    }

    public static long pastHour(Date date) {
        long t = (new Date()).getTime() - date.getTime();
        return t / 3600000L;
    }

    public static long pastMinutes(Date date) {
        long t = (new Date()).getTime() - date.getTime();
        return t / 60000L;
    }

    public static String formatDateTime(long timeMillis) {
        long day = timeMillis / 86400000L;
        long hour = timeMillis / 3600000L - day * 24L;
        long min = timeMillis / 60000L - day * 24L * 60L - hour * 60L;
        long s = timeMillis / 1000L - day * 24L * 60L * 60L - hour * 60L * 60L - min * 60L;
        long sss = timeMillis - day * 24L * 60L * 60L * 1000L - hour * 60L * 60L * 1000L - min * 60L * 1000L - s * 1000L;
        return (day > 0L ? day + "," : "") + hour + ":" + min + ":" + s + "." + sss;
    }

    public static String formatDateTime1(long timeMillis) {
        long day = timeMillis / 86400L;
        long hour = timeMillis / 3600L - day * 24L;
        long min = timeMillis / 60L - day * 24L * 60L - hour * 60L;
        long s = timeMillis - day * 24L * 60L * 60L - hour * 60L * 60L - min * 60L;
        return (day > 0L ? day + "天" : "") + hour + "小时" + min + "分" + s + "秒";
    }

    public static double getDistanceOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (double) ((afterTime - beforeTime) / 86400000L);
    }

    public static int intervalDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(6);
        int day2 = cal2.get(6);
        int year1 = cal1.get(1);
        int year2 = cal2.get(1);
        if (year1 == year2) {
//            System.out.println("判断day2 - day1 : " + (day2 - day1));
            return day2 - day1;
        } else {
            int timeDistance = 0;

            for (int i = year1; i < year2; ++i) {
                if ((i % 4 != 0 || i % 100 == 0) && i % 400 != 0) {
                    timeDistance += 365;
                } else {
                    timeDistance += 366;
                }
            }

            return timeDistance + (day2 - day1);
        }
    }

    public static int getDistanceOfTwoDateMinutes(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (int) (afterTime - beforeTime) / '\uea60';
    }

    public static boolean isValidDate(String str) {
        return isValidDate(str, "yyyy-MM-dd HH:mm");
    }

    public static boolean isValidDate(String str, String pattern) {
        boolean convertSuccess = true;
        SimpleDateFormat format = new SimpleDateFormat(pattern);

        try {
            if (str.length() != pattern.length()) {
                return false;
            }

            format.setLenient(false);
            format.parse(str);
        } catch (Exception var5) {
            convertSuccess = false;
        }

        return convertSuccess;
    }

    public static int getDaysByYearMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        Calendar a = Calendar.getInstance();
        a.set(1, cal.get(1));
        a.set(2, cal.get(2));
        a.set(5, 1);
        a.roll(5, -1);
        int maxDate = a.get(5);
        return maxDate;
    }

    public static String formatDate(String timeText, String fromFormat, String toFormat) {
        Date fromDate = null;

        try {
            fromDate = parseDate(timeText, new String[]{fromFormat});
            return formatDate(fromDate, toFormat);
        } catch (ParseException var5) {
            var5.printStackTrace();
            return null;
        }
    }

    public static Map<String, Object> getFirstAndLastOfWeek(String dataStr, String dateFormat, String resultDateFormat) throws ParseException {
        Calendar cal = Calendar.getInstance();
        cal.setTime((new SimpleDateFormat(dateFormat)).parse(dataStr));
        int d;
        if (cal.get(7) == 1) {
            d = -6;
        } else {
            d = 2 - cal.get(7);
        }

        cal.add(7, d);
        String data1 = (new SimpleDateFormat(resultDateFormat)).format(cal.getTime());
        cal.add(7, 6);
        String data2 = (new SimpleDateFormat(resultDateFormat)).format(cal.getTime());
        Map<String, Object> map = Maps.newHashMap();
        map.put("startTime", data1);
        map.put("endTime", data2);
        return map;
    }

    public static List<String> getBetweenDates(String inpstart, String inpend) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date start = null;
        Date end = null;

        try {
            start = sdf.parse(inpstart);
            end = sdf.parse(inpend);
        } catch (ParseException var8) {
            var8.printStackTrace();
        }

        List<String> result = new ArrayList();
        result.add(inpstart);
        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(start);
        tempStart.add(6, 1);
        Calendar tempEnd = Calendar.getInstance();
        tempEnd.setTime(end);

        while (tempStart.before(tempEnd)) {
            result.add(sdf.format(tempStart.getTime()));
            tempStart.add(6, 1);
        }

        result.add(inpend);
        return result;
    }

    /**
     * 计算两个日期之间相差天数.
     *
     * @param start 计算开始日期
     * @param end   计算结束日期
     * @return long 相隔天数
     * @since 1.0
     */
    public static long getDaysBetween(Date start, Date end) {
        // 将指定日期转换为yyyy-MM-dd格式
        start = DateUtils.parseDate(DateUtils.formatDate(start, parsePatterns));
        // 当前日期转换为yyyy-MM-dd格式
        end = DateUtils.parseDate(DateUtils.formatDate(end, parsePatterns));

        long diff = 0;
        if (start != null && end != null) {
            diff = (end.getTime() - start.getTime()) / DateUtils.MILLISECONDS_PER_DAY;
        }
        return diff;
    }


    public static Date getPastTime(Date referenceDate, int pastDay) {
        if (referenceDate != null && pastDay >= 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(referenceDate);
            calendar.add(6, -pastDay);
            calendar.set(11, 0);
            calendar.set(12, 0);
            calendar.set(13, 0);
            calendar.set(14, 0);
            return calendar.getTime();
        } else {
            return null;
        }
    }

    public static String getPastMonth(Date referenceDate, int pastMonth) {
        if (referenceDate != null && pastMonth >= 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(referenceDate);
            calendar.add(2, -pastMonth);
            calendar.set(5, 1);
            calendar.set(11, 0);
            calendar.set(12, 0);
            calendar.set(13, 0);
            calendar.set(14, 0);
            return formatDate(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
        } else {
            return null;
        }
    }

    public static String formatDateByTime(Date date) {
        if (getDay().equals(formatDate(date, "dd"))) {
            return formatDate(date, "HH:mm");
        } else {
            return formatDate(new Date(System.currentTimeMillis() - 86400000L), "dd").equals(formatDate(date, "dd")) ? "昨天" : formatDate(date, "MM-dd");
        }
    }

    public static int compareDate(String date1, String date2) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

        try {
            Date dt1 = df.parse(date1);
            Date dt2 = df.parse(date2);
            if (dt1.getTime() < dt2.getTime()) {
                return 1;
            } else {
                return dt1.getTime() > dt2.getTime() ? -1 : 0;
            }
        } catch (Exception var5) {
            var5.printStackTrace();
            return 0;
        }
    }

    /**
     * 当前日期加上天数后的日期，并把时间写死为23:59:59
     *
     * @param num 为增加的天数
     * @return
     */
    public static Date plusDay(int num) throws ParseException {
        Date d;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        Calendar ca = Calendar.getInstance();
        ca.add(Calendar.DATE, num);// num为增加的天数，可以改变的
        d = ca.getTime();
        String enddate = format.format(d);
        format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.parse(enddate + " 23:59:59");
    }

    /**
     * 当前日期加上天数后的日期，并把时间写死为23:59:59
     *
     * @param num 为增加的天数
     * @return
     */
    public static Date plusDay(int num, Date date) throws ParseException {
        if (date == null) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        GregorianCalendar gregorianCalendar = new GregorianCalendar();
        gregorianCalendar.setTime(date);

        gregorianCalendar.add(Calendar.DATE, num);// num为增加的天数，可以改变的
        Date d = gregorianCalendar.getTime();
        String enddate = format.format(d);
        format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.parse(enddate + " 23:59:59");
    }

    /**
     * 获取当前日期是星期几
     *
     * @param dt
     * @return 当前日期是星期几
     */
    public static String getWeekOfDate(Date dt) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);

        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;

        return weekDays[w];
    }

    /**
     * @param startTimeStr
     * @param endTimeStr
     * @return
     * @Desc 获取两个时间之间的间隔天数
     */
    public static int getCountBetweenDays(String startTimeStr, String endTimeStr) {
        int betweenDays = 0;
        Date startTime = parseDate(startTimeStr);
        Date endTime = parseDate(endTimeStr);

        long start = startTime.getTime();
        long end = endTime.getTime();

        betweenDays = (int) (Math.abs(end - start) / (24 * 3600 * 1000));

        return betweenDays + 1;
    }

    /**
     * 根据日期获取 星期
     *
     * @param datetime
     * @return
     */
    public static String dateToWeek(String datetime) {

        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
//        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        Date date;
        try {
            date = f.parse(datetime);
            cal.setTime(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //一周的第几天
        int w = cal.get(Calendar.DAY_OF_WEEK);
        return w == 1 ? "7" : String.valueOf(w - 1);
    }
}
